package com.bosssoft.service.oss.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.ObjectMetadata;
import com.bosssoft.service.oss.prop.OssProperties;
import com.bosssoft.service.oss.service.IOssService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
import java.util.UUID;

/**
 * @author Echo
 * @version 0.1.0
 * @since 2021-04-12 10:36
 **/
@Service
@Slf4j
public class OssServiceImpl implements IOssService {


    /**
     * OSS节点
     */
    private final String endPoint;

    /**
     * OSS keyID
     */
    private final String keyId;

    /**
     * OSS KeyID 对应的keySecret
     */
    private final String keySecret;

    /**
     * OSS桶名称
     */
    private final String bucketName;

    @Autowired
    public OssServiceImpl(OssProperties ossProperties) {
        this.endPoint = ossProperties.getEndpoint();
        this.bucketName = ossProperties.getBucketname();
        this.keyId = ossProperties.getKeyid();
        this.keySecret = ossProperties.getKeysecret();
    }

    @Override
    public String upload(MultipartFile file, String module) {
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return upload(inputStream, module, getUuidTypeName(Objects.requireNonNull(file.getOriginalFilename())));
    }


    @Override
    public String upload(MultipartFile file) {
        return this.upload(file, "other");
    }


    @Override
    public String upload(InputStream inputStream, String module, String fileName) {
        //设置http头令其可直接查看
        ObjectMetadata meta = new ObjectMetadata();
        meta.setContentType(getContentType(fileName.substring(fileName.lastIndexOf("."))));
        meta.setContentDisposition("inline");
        OSS ossClient = prepareOssClient();
        String key = module + "/" + fileName;
        ossClient.putObject(bucketName, key, inputStream,meta);
        closeOssClient(ossClient);
        return "https://" + bucketName + "." + endPoint + "/" + key;
    }

    public String getContentType(String fileExtension) {
        if (fileExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (fileExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (fileExtension.equalsIgnoreCase(".jpeg") ||
                fileExtension.equalsIgnoreCase(".jpg") ||
                fileExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        if (fileExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (fileExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (fileExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (fileExtension.equalsIgnoreCase(".pptx") ||
                fileExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (fileExtension.equalsIgnoreCase(".docx") ||
                fileExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (fileExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        return "image/jpg";
    }

    @Override
    public byte[] download(String module, String fileName) {
        OSS oss = prepareOssClient();
        InputStream objectContent = oss.getObject(bucketName, module + "/" + fileName).getObjectContent();
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            IOUtils.copy(objectContent, outputStream);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        closeOssClient(oss);
        return outputStream.toByteArray();
    }

    @Override
    public byte[] download(String fileName) {
        return download("other", fileName);
    }


    /**
     * 准备OSS客户端，同时检查桶是否有效
     *
     * @return OSS客户端
     * @version 0.1.0
     * @author Echo
     * @since 2021/4/15 13:40
     */
    private OSS prepareOssClient() {
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endPoint, keyId, keySecret);
        if (!ossClient.doesBucketExist(bucketName)) {
            ossClient.createBucket(bucketName);
            ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
        }
        return ossClient;
    }

    /**
     * 关闭OSS客户端
     *
     * @param ossClient OSS客户端
     * @version 0.1.0
     * @author Echo
     * @since 2021/4/15 11:20
     */
    private void closeOssClient(OSS ossClient) {
        ossClient.shutdown();
    }


    /**
     * 获取UUID类型文件名
     *
     * @param originalFilename 源文件名，需要带有后缀
     * @return UUID类型文件名
     * @version 0.1.0
     * @author Echo
     * @since 2021/4/15 13:40
     */
    private String getUuidTypeName(String originalFilename) {
        String fileName = UUID.randomUUID().toString();
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        return fileName + fileExtension;
    }


}
